import re


def replace_var_dict(template, data):
    pattern = re.compile(r'\$\{(\w+)\}')
    if isinstance(template, str):
        result = pattern.sub(lambda x: str(data.get(x.group(1).strip(), x.group(0))), template)
        result = is_int(pattern, template, result, data)
    elif isinstance(template, dict):
        result = {}
        for key, value in template.items():
            if isinstance(value, str):
                result[key] = pattern.sub(lambda x: str(data.get(x.group(1).strip(), x.group(0))), value)
                result[key] = is_int(pattern, value, result[key], data)
            elif isinstance(value, (dict, list)):
                result[key] = (replace_var_dict(value, data))
            else:
                result[key] = value
    elif isinstance(template, list):
        result = []
        for item in template:
            if isinstance(item, str):
                value = (pattern.sub(lambda x: str(data.get(x.group(1).strip(), x.group(0))), item))
                # result.append
                result.append(is_int(pattern, item, value, data))
            elif isinstance(item, (dict, list)):
                result.append(replace_var_dict(item, data))
            else:
                result.append(item)
    else:
        result = template
    return result


def is_int(pattern, value, result, data):
    var_str = re.search(pattern, value)
    if var_str:
        if data.get(var_str.group(1), None) and type(data[var_str.group(1)]) == int:
            if isinstance(result, str):
                try:
                    return eval(result)
                except:
                    return int(result)
    return result


if __name__ == '__main__':
    template = ['${token}']
    data = {
        'token': 10,
        'friends': ['Bob', 'Charlie'],
        "name": 123
    }
    result = replace_var_dict(template, data)
    print(result)
